﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AccCoreLib;
using Giraffe.Core.Common.Messengers;

namespace Giraffe.Core.ICQ
{
    internal class IcqContactsManager
    {
        private Dictionary<string, IcqContact> _contactsDict = new Dictionary<string, IcqContact>();
        private IcqSession _icqSession;
        private IMessengerContact _ownContact;

        public event Action ContactListChanged;
        public event Action<IMessengerContact> ContactChanged;

        public IcqContactsManager(IcqSession session, string ownContactName)
        {
            _ownContact = new IcqContact(ownContactName);
            _icqSession = session;
            _icqSession.Session.OnUserChange += OnContactChanged;
        }

        private void OnInvite(AccSession session, IAccSecondarySession secondarysession, string username, int transid, AccResult hr)
        {
            throw new NotImplementedException();
        }

        public IMessengerContact OwnContact
        {
            get
            {
                return _ownContact;
            }
        }

        public IEnumerable<IMessengerContact> ContactList
        {
            get
            {
                foreach (IcqContact contact in _contactsDict.Values)
                {
                    yield return contact;
                } 
            }
        }

        public void UpdateContacts()
        {
            IAccBuddyList buddyList = _icqSession.Session.BuddyList;
            int groupCount = buddyList.GroupCount;
            for (int i = 0; i < groupCount; i++)
            {
                IAccGroup group = buddyList.GetGroupByIndex(i);
                int buddyCount = group.BuddyCount;
                for (int j = 0; j < buddyCount; j++)
                {
                    IAccUser buddy = group.GetBuddyByIndex(j);
                    var buddyState = (AccUserState) buddy.get_Property(AccUserProp.AccUserProp_State);

                    var contact = new IcqContact(buddy.Name);
                    contact.GroupName = group.Name;
                    contact.IcqUserState = buddyState;
                    try
                    {
                        contact.Name = buddy.get_Property(AccUserProp.AccUserProp_FriendlyName).ToString();
                    }
                    catch (Exception)
                    {
                        contact.Name = buddy.Name;
                    }

                    _contactsDict[contact.ID]= contact;
                }
            }
            OnContactListChanged();              
        }

        public IcqContact this[string id]
        {
            get
            {
                return _contactsDict[id];
            }
        }

        private void OnContactChanged(AccSession session, IAccUser olduser, IAccUser newuser, AccUserProp property, AccResult hr)
        {
            if (newuser.Name == _ownContact.ID || !_contactsDict.ContainsKey(newuser.Name)) return;

            if (property == AccUserProp.AccUserProp_State)
            {
                IcqContact contact = _contactsDict[newuser.Name];
                contact.IcqUserState = (AccUserState)newuser.get_Property(AccUserProp.AccUserProp_State);

                if (ContactChanged != null)
                {
                    ContactChanged(contact);
                }
            }
        }
        
        private void OnContactListChanged()
        {
            if (ContactListChanged != null)
            {
                ContactListChanged();
            }
        }
    }
}
